package com.self.task;

import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class TaskExecutor implements Runnable{

    private BlockingDeque<AsyncTask> taskDeque = new LinkedBlockingDeque<>();

    private ThreadPoolExecutor poolExecutor;

    private AtomicBoolean alive = new AtomicBoolean(true);

    private long waitTimeoutMs = 30000;

    private BusinessHandler businessHandler;

    public void shutdown() {
        alive.set(false);
    }

    public boolean addTask(AsyncTask asyncTask) {
        return taskDeque.offerLast(asyncTask);
    }

    @Override
    public void run() {

        loadTasks();

        while (alive.get()) {

            try {

                AsyncTask asyncTask = taskDeque.poll(waitTimeoutMs, TimeUnit.MILLISECONDS);

                if(asyncTask != null) {

                    // 业务处理器
                    BusinessHandler businessHandler = BusinessHandlerLoader.loadHandler(asyncTask.businessHandler);

                    if(businessHandler != null) {

                        // 调度执行业务处理器
                        poolExecutor.submit(() -> {

                            TaskStatus taskStatus = businessHandler.handle(asyncTask);

                            switch (taskStatus) {
                                case FAILURE:
                                    notifyOnFailure(asyncTask);
                                    break;
                                case WAITING:
                                case RETRY:
                                    taskDeque.offerLast(asyncTask);
                                    break;
                                case SUCCESS:
                                    log();
                                    break;
                                default:
                                    break;

                            }
                        });
                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
            }


        }
    }

    private void loadTasks() {

    }

    private void notifyOnFailure(AsyncTask asyncTask) {

    }

    private void log() {

    }

    public static void main(String[] args) {

        ReadWriteLock readWriteLock = new ReentrantReadWriteLock();

        try {

            readWriteLock.readLock().lock();

            System.out.println("获取读锁");
            try {

                readWriteLock.writeLock().lock();
                System.out.println("锁升级 >>> 获取读锁后再获取写锁");

                readWriteLock.readLock().lock();
                System.out.println("释放读锁");
            } finally {
                readWriteLock.readLock().unlock();
                readWriteLock.readLock().unlock();
                readWriteLock.readLock().unlock();
                System.out.println("释放写锁");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
